﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.IO;
using System.Windows.Media.Imaging;
using System.Collections.Specialized;
using System.Threading;
using System.Windows.Input;

namespace RecommendatioNetwork.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {

        #region Variabili e Proprietà Interfaccia Rete
        private ObservableCollection<KeyValuePair<Uri, Ranking>> _neighbors = new ObservableCollection<KeyValuePair<Uri, Ranking>>((Application.Current as App).MyModel.MyRepository.UrisRank.ToList());
        public ObservableCollection<KeyValuePair<Uri, Ranking>> Neighbors
        {
            get { return _neighbors; }
            set { _neighbors = value; }
        }
        private string _address = (Application.Current as App).MyModel.MyRepository.IPserver;
        public string Address { 
            get { return _address; } 
            set { _address = value; } 
        }
        private string _port = "8181";
        public string Port { get { return _port; } set { _port = value; } }
        private bool _serverStarted = false;
        public bool ServerStarted
        {
            get { return _serverStarted; }
            set
            {
                _serverStarted = value;
                this.OnPropertyChanged("ServerStarted");
            }
        }
        #endregion

        #region Variabili e Proprietà Interfaccia Commenti
        private ObservableCollection<Comment> _comments = new ObservableCollection<Comment>((Application.Current as App).MyModel.MyRepository.MyComments);
        public ObservableCollection<Comment> Comments
        {
            get { return _comments; }
            set { _comments = value; }
        }
        private ObservableCollection<string> _typology = new ObservableCollection<string> {"Beauty", "Books", "Cameras", "Cars and Motorcycles", "Computers", "Computer Components", "Electronics", "Family", "Finance", "Games", "House and Garden", "Household Appliances", "Kitchen Appliances", "Movies", "Music", "Sports and Outdoors", "Telecommunications", "Travel", "TVs", "More Categories" }; 
        public ObservableCollection<string> Typology
        {
            get {
                return  _typology; 
            }
        }

        public string SelectedTypology{ set; get;}
        private string _index;
        public string Index
        {
            get { return _index; }
            set { _index = value;
            this.OnPropertyChanged("Index");
            }
            //{
            //    if (string.IsNullOrEmpty(value))
            //        throw new ArgumentNullException("Il titolo del commento non può essere vuoto");
            //    else
            //        _index = value;
            //    this.OnPropertyChanged("Index");
            //}
        }
        private string _textComment;
        public string TextComment
        {
            get { return _textComment; }
            set { _textComment = value;
            this.OnPropertyChanged("TextComment");
            }
        }
        
        private ObservableCollection<string> _valuesRating = new ObservableCollection<string> { "Nessuna valutazione", "Scadente", "Mediocre", "Sufficiente", "Buono", "Ottimo" };
        public ObservableCollection<string> ValueRating
        {
            get { return _valuesRating; }
        }
        private uint _rating=0;

        public uint Rating
        {
            get { return _rating; }
            set { _rating = value; }
        }
        
        //public uint Rating { get; set; }
        public Comment CommentToRemove { get; set; }
        #endregion

        #region Variabili e Proprietà  Interfaccia Ricerca

        private ObservableCollection<KeyValuePair<Search, ObservableCollection<Comment>>> _activeSearch = new ObservableCollection<KeyValuePair<Search, ObservableCollection<Comment>>>(Converter((Application.Current as App).MyModel.MyRepository.ActiveSearch));
        public ObservableCollection<KeyValuePair<Search, ObservableCollection<Comment>>> ActiveSearch
        {
            get { return _activeSearch; }
            set { _activeSearch = value; }
        }
        //Converte la lista di commenti all'interno del dizionario in una collezione osservabile di commenti 
        private static Dictionary<Search, ObservableCollection<Comment>> Converter(Dictionary<Search, List<Comment>> dictionary)
        {
            Dictionary<Search, ObservableCollection<Comment>> dicObservable = new Dictionary<Search, ObservableCollection<Comment>>();
            foreach (KeyValuePair<Search, List<Comment>> kvp in dictionary)
            {
                dicObservable.Add(kvp.Key, new ObservableCollection<Comment>(kvp.Value));
            }
            return dicObservable;
        }
        private ObservableCollection<string> _typologySearched = new ObservableCollection<string> { "All Categories", "Beauty", "Books", "Cameras", "Cars and Motorcycles", "Computers", "Computer Components", "Electronics", "Family", "Finance", "Games", "House and Garden", "Household Appliances", "Kitchen Appliances", "Movies", "Music", "Sports and Outdoors", "Telecommunications", "Travel", "TVs", "More Categories" };
        /// <summary>
        /// Lista delle tipologie da cercare
        /// </summary>
        public ObservableCollection<string> TypologySearched
        {
            get { return _typologySearched; }
        }
        private ObservableCollection<string> _typeOfSearch = new ObservableCollection<string> { "Titolo","Titolo e testo" };
        /// <summary>
        /// Lista delle modalità di ricerca
        /// </summary>
        public ObservableCollection<string> TypeOfSearch
        {
            get { return _typeOfSearch; }
        }
        /// <summary>
        /// Tipologia di ricerca selezionata
        /// </summary>
        public string TypeOfSearchSelected { get; set; }
        /// <summary>
        /// Tipologia di commento selezionata per la ricerca
        /// </summary>
        public string TypologySearchedSelected { get; set; }
        private string _indexSearched="";

        public string IndexSearched
        {
            get { return _indexSearched; }
            set { _indexSearched = value; }
        }
        
        public Comment SelectedItemComment { get; set; }
        private TabControl _tabController = new TabControl();
        public TabControl TabController { 
            get { return _tabController; } 
            set { _tabController = value; } 
        }
        public ObservableCollection<TabItem> TabItems { get; set; }
        public TabItem SelectedTabItem { get; set; }
        
        #endregion

        #region Variabili e Proprietà Interfaccia Configurazione
        private Configuration _configuration = (Application.Current as App).MyModel.MyConfiguration;
        private Configuration _DeafualtConfiguration = new Configuration();
        public Configuration LoadConfiguration
        {
            get { return _configuration; }
            set { _configuration = value;}
        }
        public Configuration DefaultConfiguration
        {
            get { return _DeafualtConfiguration; }
            set { _DeafualtConfiguration = value; }
        }
        #endregion

        #region Variabili e Proprietà Interfaccia Comune

        private string _output;
        public string Output
        {
            get { return _output; }
            set { _output = value; OnPropertyChanged("Output"); }
        }

        //private ICollectionView view;
        private Model MyModel = (Application.Current as App).MyModel;

        #endregion



        #region Commmands
        public DelegateCommand AddNeighborsCommand { get; private set; }
        public DelegateCommand RemoveNeighborsCommand { get; private set; }
        public DelegateCommand RemoveAllNeighborsCommand { get; private set; }
        public DelegateCommand AddCommentCommand { get; private set; }
        public DelegateCommand DeleteAllCommentCommand { get; private set; } 
        public DelegateCommand DeleteCommentCommand { get; private set; } 
        public DelegateCommand DeleteCommentFromListCommand { get; private set; }
        public DelegateCommand ConnectServerCommand { get; private set; }
        public DelegateCommand StopServerCommand { get; private set; }
        public DelegateCommand SearchCommentCommand { get; private set; }
        public DelegateCommand ToZeroCommand { get; private set; }
        public DelegateCommand SaveCommentCommand { get; private set; }
        public DelegateCommand DefaultConfigurationCommand { get; private set; }
        public DelegateCommand RemoveActiveSearchCommand { get; private set; }
       

        #endregion

        #region Costruttore
        public MainWindowViewModel()
        {
            
            Output = "Programma avviato il " + System.DateTime.Now;
            //setting elementi selezionati di default nelle combobox
            this.SelectedTypology=_typology.ElementAt(0);
            this.TypologySearchedSelected = _typologySearched.ElementAt(0);
            this.TypeOfSearchSelected = _typeOfSearch.ElementAt(0);
            //sottoscrizione Eventi dal repository
            MyModel.MyRepository.neighborsChanged += new EventHandler(OnNeighborsChanged);
            MyModel.MyRepository.activeSearchChanged += new EventHandler(OnActiveSearchChanged);
            Listener.listnerSearch += new EventHandler(OnRouting);

            //set DelegateCommand
            this.AddNeighborsCommand = new DelegateCommand((o) => this.AddNeighbor(), (o) => CanAddNeighbor());
            this.RemoveNeighborsCommand = new DelegateCommand((o) => RemoveNeighbor(o), o => o != null);
            this.RemoveAllNeighborsCommand = new DelegateCommand((o) => RemoveAllNeighbor(), o => Neighbors.Count != 0);
            this.AddCommentCommand = new DelegateCommand((o) => this.AddNewComment());
            this.DeleteCommentCommand = new DelegateCommand((o) => this.DeleteComment(o), o => CanDeleteComment(o));
            this.DeleteAllCommentCommand = new DelegateCommand((o) => this.DeleteAllComment(), o => CanDeleteAllComment());
            this.ConnectServerCommand = new DelegateCommand((o) => this.StartServer(), o => !ServerStarted);
            this.StopServerCommand = new DelegateCommand((o) => this.StopServer(), o => ServerStarted);
            this.SearchCommentCommand = new DelegateCommand((o) => this.NewSearch(), o => ServerStarted);
            this.ToZeroCommand = new DelegateCommand((o) => ToZero());
            this.SaveCommentCommand = new DelegateCommand((o) => this.SaveComment(), o => CanSaveComment());
            this.DeleteCommentFromListCommand = new DelegateCommand((o) => this.DeleteFromListComment(), o => CanDeleteFromListComment());
            this.DefaultConfigurationCommand = new DelegateCommand((o) => DefaultConf());
            this.RemoveActiveSearchCommand = new DelegateCommand((o) => RemoveActiveSearch(o));

            this.LoadList();
        }

        #endregion


        #region Metodi Interfaccia Rete

        public bool StartServer()
        {
            try
            {
                try
                {
                    ServerStarted = MyModel.InitializeCommunication();
                    OnPropertyChanged("MyUri");
                    if (ServerStarted)
                        Output = "Server correttamente avviato su " + MyModel.MyRepository.MyUri;//il " + System.DateTime.Now;
                }
                catch (Exception ee) { MessageBox.Show(ee.ToString()); }
                return ServerStarted;

            }
            catch (Exception ee) { MessageBox.Show(ee.ToString()); return false; }
        }

        public bool StopServer()
        {
            try
            {
                MyModel.MyServiceHost.Close();
                Output = "Server disabilitato il " + System.DateTime.Now;
                return ServerStarted = false;
            }
            catch (Exception) { return ServerStarted = true; }
        }

        private void AddNeighbor()
        {
            //codice che aggiunge il neig. al Model
            try
            {

                Console.WriteLine("AddNeighbors");
                UriBuilder ubuild = new UriBuilder("http", Address, Convert.ToInt32(Port), MyModel.MyConfiguration.ServiceName);
                Uri ub = ubuild.Uri;//new Uri("http://" +  + ":" + Port + "/" + );
                Ranking ranking = new Ranking(MyModel.MyConfiguration) { Request = 1, Response = 1, RequestFailed = 0 };
                MyModel.MyRepository.UrisRank.Add(ub, ranking);
                MyModel.MyRepository.CheckListOfNeighborIsNotFull();
                MyModel.MyRepository.OnNeighborsChanged(EventArgs.Empty);//****************
                Output = "Nuovo nodo aggiunto correttamente il " + System.DateTime.Now;
                Address = null;
                this.OnPropertyChanged("Address");
                Port = null;
                this.OnPropertyChanged("Port");
                //this.UpdateModel();
            }
            catch (System.ArgumentException) { MessageBox.Show("Il nodo che hai inserito è gia contenuto nella lista", "Nodo presente", MessageBoxButton.OK, MessageBoxImage.Information); }
            catch (Exception ee) { MessageBox.Show(ee.ToString()); }
        }
        
        private bool CanAddNeighbor()
        {
            if (Address == null || Port == null)
                return false;
            Char[] separator = new Char[] { '.', '.', '.' };
            String[] result = Address.Split(separator);
            if (result.Count() != 4)
                return false;
            int[] ints;
            int port;
            try
            {
                ints = result.Select(x => int.Parse(x)).ToArray();
                port=Convert.ToInt16(Port);            
            }
            catch (Exception) { return false; }
            if (port <= 1024 || port > 65536)
                return false;
            foreach (int i in ints)
            {
                if (i < 0 || i > 255)
                    return false;
            }
            return true;
        }

        private void RemoveNeighbor(object obj)
        {
            MessageBoxResult msb = MessageBox.Show("Sei sicuro di voler eliminare il nodo?", "Eliminazione nodo", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (msb == MessageBoxResult.No)
                return;
            KeyValuePair<Uri, Ranking> kvp = (KeyValuePair<Uri, Ranking>)obj;
            MyModel.MyRepository.UrisRank.Remove(kvp.Key);
            MyModel.MyRepository.OnNeighborsChanged(EventArgs.Empty);//****************
            Output = "Eliminazione nodo eseguita correttamente il " + System.DateTime.Now;
        }

        private void RemoveAllNeighbor()
        {
            MessageBoxResult msb = MessageBox.Show("Sei sicuro di voler eliminare tutti i nodi?", "Eliminazione nodi", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (msb == MessageBoxResult.No)
                return;
            MyModel.MyRepository.UrisRank.Clear();
            MyModel.MyRepository.OnNeighborsChanged(EventArgs.Empty);//****************
            Output = "Eliminazione dei nodi eseguita correttamente il " + System.DateTime.Now;
        }
        #endregion

        #region Meotdi Inferfaccia Commenti
        private void AddNewComment()
        {
            Comment c = new Comment(MyModel.MyRepository.MyPeer,SelectedTypology, Index, TextComment, Rating);
            MyModel.MyRepository.MyComments.Add(c);
            RefreshComments();
            Output = "Aggiunto un nuovo commento il " + System.DateTime.Now;
            this.SelectedTypology = _typology.ElementAt(0);
            this.OnPropertyChanged("SelectedTypology");
            this.Rating = 0;
            this.OnPropertyChanged("Rating");
            Index = null;
            TextComment = null;
            
        }

        private void DeleteComment(Object obj)
        {
            try
            {
                MessageBoxResult msb = MessageBox.Show("Sei sicuro di voler eliminare il commento?", "Eliminazione commenti", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (msb == MessageBoxResult.No)
                    return;
                Comment c = obj as Comment;
                MyModel.MyRepository.MyComments.Remove(c);
                RefreshComments(); 
                OnPropertyChanged("Comments");
                Output = "Eliminato commento il " + System.DateTime.Now;
            }
            catch (Exception ee) { MessageBox.Show(ee.ToString()); }
        }

        private bool CanDeleteComment(Object obj)
        {
            if (obj == null)
                return false;
            Comment c = obj as Comment;
            if (!MyModel.MyRepository.MyComments.Contains(c))
                return false;
            else return true;
        }

        private void DeleteAllComment()
        {
            try
            {
                MessageBoxResult msb=MessageBox.Show("Sei sicuro di voler eliminare tutti i commenti?", "Eliminazione commenti", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (msb == MessageBoxResult.No)
                    return;
                MyModel.MyRepository.MyComments.Clear();
                RefreshComments();
                OnPropertyChanged("Comments");
                Output = "Eliminati tutti i commenti in data " + System.DateTime.Now;
            }
            catch (Exception ee) { MessageBox.Show(ee.ToString()); }
        }

        private bool CanDeleteAllComment()
        {
            if (MyModel.MyRepository.MyComments.Count()==0)
                return false;
            else return true;
        }
        #endregion

        #region Metodi Interfaccia Ricerca
        public void NewSearch()
        {  
            ObservableCollection<Comment> obsComment = new ObservableCollection<Comment>();
            try
            {

                Search search = new Search(MyModel) { Typology = TypologySearchedSelected, TextSearched = IndexSearched, TypeOfSearch = TypeOfSearchSelected };
                //MessageBox.Show(search.Typology+" "+search.TextSearched+" "+search.TypeOfSearch);
                MyModel.MyRepository.ActiveSearch.Add(search, new List<Comment>());
                ActiveSearch.Add(new KeyValuePair<Search, ObservableCollection<Comment>>(search, obsComment));
                TabItem ti=CreateTabItem(search, obsComment);
                TabItems.Add(ti);
                SelectedTabItem = ti;
                OnPropertyChanged("TabItems");
                OnPropertyChanged("SelectedTabItem");               
                ThreadStart threadSearch = delegate { MyModel.MySender.SearchComments(search); };
                new Thread(threadSearch).Start();
            }
            catch (Exception ee) { MessageBox.Show(ee.ToString()); }
        }

        public void ToZero(){
            IndexSearched = "";
            TypologySearchedSelected = _typologySearched.ElementAt(0);
            TypeOfSearchSelected = _typeOfSearch.ElementAt(0);
            OnPropertyChanged("IndexSearched");
            OnPropertyChanged("TypologySearchedSelected");
            OnPropertyChanged("TypeOfSearchSelected");
        }

        public void LoadList()
        {
            //TabController = tabControl;
            //carico la lista di tabItem
            TabItems = new ObservableCollection<TabItem>();
            foreach (KeyValuePair<Search, ObservableCollection<Comment>> kvp in ActiveSearch)
            {
                //carico la lista di tabItem   
                TabItems.Add(CreateTabItem(kvp.Key, kvp.Value));
                OnPropertyChanged("TabItems");
            }
        }

        private TabItem CreateTabItem(Search search, ObservableCollection<Comment> obsComment)
        {
            DataGrid dg = createDataGrid();
            dg.Name = "DataGridInTab";
            dg.AutoGenerateColumns = false;
            dg.ItemsSource = obsComment;
            dg.SelectionMode=DataGridSelectionMode.Single; 
            dg.HeadersVisibility=DataGridHeadersVisibility.Column;
            dg.IsReadOnly = true;            
            dg.MouseDoubleClick += DataGridOnClick;

            TabItem ti = new TabItem();
            StackPanel sp = new StackPanel();
            sp.Orientation = System.Windows.Controls.Orientation.Horizontal;
            TextBlock tb = new TextBlock();
            tb.Text = search.TextSearched + "  ";
            Button button = new Button();
            Image imageButton = new Image();
            BitmapImage buttonX = new BitmapImage();
            buttonX.BeginInit();
            buttonX.StreamSource = new MemoryStream(File.ReadAllBytes("../../View/Images/tabClose.png"));
            buttonX.EndInit();
            imageButton.Source = buttonX;
            button.Content = imageButton;
            sp.Children.Add(tb);
            sp.Children.Add(button);
            ti.Header = sp;// +" (" + obsComment.Count + ")";
            //ti.Name = "Id"+IndexSearched;
            ti.Content = dg;
            button.CommandParameter = new TabSearch() { TabItem = ti, Search = search };
            button.Command = RemoveActiveSearchCommand;
            return ti;
            //TabController.Items.Add(ti);
            //TabController.Items.Refresh();
            //TabController.SelectedItem = ti;
            //OnPropertyChanged("TabController");

        }

        private DataGrid createDataGrid()
        {
            DataGrid dg = new DataGrid();
            dg.AutoGenerateColumns = false;
            dg.IsReadOnly = true;
            

            DataGridTextColumn TypologyColumn = new DataGridTextColumn();
            TypologyColumn.Header = "Tipologia";
            Binding b = new Binding("Typology");
            b.Mode = BindingMode.OneWay;
            TypologyColumn.Binding = b;
            dg.Columns.Add(TypologyColumn);

            DataGridTextColumn IndexColumn = new DataGridTextColumn();
            IndexColumn.Header = "Titolo";
            b = new Binding("NameIndex");
            b.Mode = BindingMode.OneWay;
            IndexColumn.Binding = b;
            dg.Columns.Add(IndexColumn);

            DataGridTextColumn peerColumn = new DataGridTextColumn();
            peerColumn.Header = "Creatore";
            b = new Binding("PeerName");
            b.Mode = BindingMode.OneWay;
            peerColumn.Binding = b;
            dg.Columns.Add(peerColumn);

            DataGridTextColumn TSColumn = new DataGridTextColumn();
            TSColumn.Header = "Data Creazione";
            b = new Binding("TimeStamp");
            b.Mode = BindingMode.OneWay;
            TSColumn.Binding = b;
            dg.Columns.Add(TSColumn);

            DataGridTextColumn RRColumn = new DataGridTextColumn();
            RRColumn.Header = "Fonti";
            b = new Binding("ReplyResponse");
            b.Mode = BindingMode.OneWay;
            RRColumn.Binding = b;
            dg.Columns.Add(RRColumn);

            return dg;
        }

        private void SaveComment()
        {
            Comment c = this.SelectedItemComment;
            MyModel.MyRepository.MyComments.Add(c);
            Comments.Add(c);
            OnPropertyChanged("Comments");
        }

        private bool CanSaveComment()
        {
            if (this.SelectedItemComment == null || MyModel.MyRepository.MyComments.Contains(this.SelectedItemComment))
                return false;
            else return true;
        }

        private void DeleteFromListComment()
        {
            Comment c = this.SelectedItemComment;
            foreach (KeyValuePair<Search, ObservableCollection<Comment>> kvp in ActiveSearch)
            {
                kvp.Value.Remove(c);
                break;
            }
            foreach (KeyValuePair<Search, List<Comment>> kvp in MyModel.MyRepository.ActiveSearch)
            {
                kvp.Value.Remove(c);
                break;
            }
            SelectedItemComment = null;
            OnPropertyChanged("ActiveSearch");
            OnPropertyChanged("SelectedItemComment");
        }

        private bool CanDeleteFromListComment()
        {
            if (this.SelectedItemComment == null)
                return false;
            Comment c = this.SelectedItemComment;
            foreach (KeyValuePair<Search, ObservableCollection<Comment>> kvp in ActiveSearch)
            {
                kvp.Value.Contains(c);
                return true;
            }

            return false;
        }

        private void DataGridOnClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            DataGrid dg = sender as DataGrid;
            DataGridRow row = ItemsControl.ContainerFromElement(dg, e.OriginalSource as DependencyObject) as DataGridRow;
            if (row != null)
            {
                try
                {
                    Comment comment = dg.CurrentItem as Comment;
                    SelectedItemComment = dg.CurrentItem as Comment;
                    OnPropertyChanged("SelectedItemComment");
                    //MessageBox.Show(comment.TextComment);
                }
                catch (Exception ee) { MessageBox.Show(ee.ToString()); }
            }
        }

        private void RemoveActiveSearch(object obj)
        {
            try
            {
                TabSearch ts = obj as TabSearch;
                //TabController.Items.Remove(ts.TabItem);
                TabItems.Remove(ts.TabItem);
                OnPropertyChanged("TabItems");
                foreach (KeyValuePair<Search, ObservableCollection<Comment>> kvp in ActiveSearch)
                {
                    if (ts.Search.Equals(kvp.Key))
                    {
                        MyModel.MyRepository.ActiveSearch.Remove(kvp.Key);
                        ActiveSearch.Remove(kvp);
                        break;
                    }
                }
                //OnPropertyChanged("ActiveSearch");
                //MessageBox.Show("not obs:"+(Application.Current as App).MyModel.MyRepository.ActiveSearch.Count + " obs:"+ActiveSearch.Count);    
            }
            catch (Exception e) { MessageBox.Show(e.ToString()); }
        }

        #endregion

        #region Metodi Interfaccia Configurazione
        public void DefaultConf()
        {
            MessageBoxResult msb = MessageBox.Show("Sei sicuro di voler ripristinare la configurazione iniziale?", "Resetta Configurazione", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (msb == MessageBoxResult.No)
                return;
            LoadConfiguration = DefaultConfiguration;
            OnPropertyChanged("LoadConfiguration");
        }
        #endregion

        #region Eventi ascoltati dal model
        public void OnNeighborsChanged(Object sender, EventArgs x)
        {
            //MessageBox.Show("Gestore OnNeighborsChanged");
            Neighbors = new ObservableCollection<KeyValuePair<Uri, Ranking>>((sender as Repository).UrisRank);
            OnPropertyChanged("Neighbors");
        }
        public void OnActiveSearchChanged(Object sender, EventArgs x)
        {
            Packet p = x as Packet; 
            foreach (KeyValuePair<Search, ObservableCollection<Comment>> kvp in ActiveSearch)
            {
                if (string.Equals(kvp.Key.KeyRequest, p.Search.KeyRequest, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (kvp.Value.Contains(p.Comment)) {
                        kvp.Value.Remove(p.Comment);
                    }
                    ActiveSearch.Remove(kvp);
                    kvp.Value.Add(p.Comment);
                    ActiveSearch.Add(kvp);
                    OnPropertyChanged("ActiveSearch");
                    OnPropertyChanged("TabItems");
                    break;
                }
            }
        }
        public void OnRouting(Object sender, EventArgs x) {
            Search search = x as Search;
            Output = "Arrivata richiesta da parte di " + search.Uri.ToString();
            OnPropertyChanged("Output");
        }
        #endregion

        #region Altri Metodi di supporto
       
        public void RefreshComments() { 
        Comments =new ObservableCollection<Comment>(MyModel.MyRepository.MyComments);
        OnPropertyChanged("Comments");
        }
        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            Console.WriteLine("Property Changed");
        }

        #endregion

        #region Classe di supporto
        private class TabSearch {
            public Search Search { get; set; }
            public TabItem TabItem { get; set; }

        }
        #endregion
    }

}
